const std = @import("std");

// 添加 Semaphore 类型定义
pub const Semaphore = struct {
    count: std.atomic.Value(i32),
    
    pub fn init(initial_count: i32) Semaphore {
        return Semaphore{
            .count = std.atomic.Value(i32).init(initial_count),
        };
    }
    
    pub fn wait(self: *Semaphore) void {
        while (true) {
            const current = self.count.load(.acquire);
            if (current > 0) {
                if (self.count.cmpxchgWeak(current, current - 1, .acq_rel, .acquire)) |_| {
                    continue;
                } else {
                    break;
                }
            }
            std.Thread.yield() catch {};
        }
    }
    
    pub fn signal(self: *Semaphore) void {
        _ = self.count.fetchAdd(1, .acq_rel);
    }
    
    pub fn create(allocator: std.mem.Allocator, initial_count: i32, _: i32) !*Semaphore {
        const sem = try allocator.create(Semaphore);
        sem.* = Semaphore.init(initial_count);
        return sem;
    }

    pub fn acquire(self: *Semaphore) void {
        self.wait();
    }
    
    pub fn release(self: *Semaphore) void {
        self.signal();
    }
    
    pub fn destroy(self: *Semaphore, allocator: std.mem.Allocator) void {
        allocator.destroy(self);
    }
};
const api = @import("api.zig");

// 物理内存块结构
const PhysicalMemoryBlock = struct {
    base: api.PhysicalAddress,
    size: u64,
    free: bool,
};

// 内存区域类型
pub const MemoryRegionType = enum {
    free,
    reserved,
    acpi_reclaimable,
    acpi_nvs,
    bad_memory,
};

// 内存区域描述
const MemoryRegion = struct {
    base: api.PhysicalAddress,
    size: u64,
    type: MemoryRegionType,
};

// 内存管理器
pub const MemoryManager = struct {
    allocator: std.mem.Allocator,
    memory_regions: std.ArrayList(MemoryRegion),
    free_blocks: std.ArrayList(PhysicalMemoryBlock),
    page_size: u64 = 4096, // 默认页大小为4KB

    // 初始化内存管理器
    pub fn init(allocator: std.mem.Allocator) !MemoryManager {
        const manager = MemoryManager{
            .allocator = allocator,
            .memory_regions = std.ArrayList(MemoryRegion).init(allocator),
            .free_blocks = std.ArrayList(PhysicalMemoryBlock).init(allocator),
        };

        return manager;
    }

    // 设置内存映射
    pub fn setupMemoryMap(self: *MemoryManager) !void {
        // 在实际系统中，这里会从BIOS或UEFI获取内存映射信息
        // 这里我们模拟添加一些内存区域

        // 添加一个16MB的可用内存区域
        try self.memory_regions.append(MemoryRegion{
            .base = 0x100000, // 1MB起始位置
            .size = 0xF00000, // 15MB大小
            .type = .free,
        });

        // 添加一个保留区域（例如BIOS ROM）
        try self.memory_regions.append(MemoryRegion{
            .base = 0xF00000, // 15MB起始位置
            .size = 0x100000, // 1MB大小
            .type = .reserved,
        });

        // 初始化空闲块列表
        for (self.memory_regions.items) |region| {
            if (region.type == .free) {
                try self.free_blocks.append(PhysicalMemoryBlock{
                    .base = region.base,
                    .size = region.size,
                    .free = true,
                });
            }
        }
    }

    // 分配物理内存
    pub fn allocatePhysicalMemory(self: *MemoryManager, size: u64, alignment: u64) ?api.PhysicalAddress {
        // 对齐大小到页边界
        const aligned_size = std.mem.alignForward(u64, size, self.page_size);

        // 简单的首次适配算法
        for (self.free_blocks.items, 0..) |*block, i| {
            if (block.free and block.size >= aligned_size) {
                const alloc_addr = block.base;

                // 检查对齐要求
                const aligned_addr = std.mem.alignForward(u64, alloc_addr, alignment);
                const alignment_padding = aligned_addr - alloc_addr;

                // 如果对齐后空间不足，继续查找
                if (block.size - alignment_padding < aligned_size) {
                    continue;
                }

                // 分割块（如果剩余空间足够大）
                if (block.size - alignment_padding - aligned_size > self.page_size) {
                    // 创建新的空闲块
                    self.free_blocks.insert(i + 1, PhysicalMemoryBlock{
                        .base = aligned_addr + aligned_size,
                        .size = block.size - alignment_padding - aligned_size,
                        .free = true,
                    }) catch {
                        return null;
                    };
                }

                // 更新当前块
                if (alignment_padding > 0) {
                    block.size = alignment_padding;
                } else {
                    block.free = false;
                    block.size = aligned_size;
                }

                return aligned_addr;
            }
        }

        return null; // 没有找到合适的空闲块
    }

    // 释放物理内存
    pub fn freePhysicalMemory(self: *MemoryManager, addr: api.PhysicalAddress, size: u64) bool {
        // 对齐大小到页边界
        const aligned_size = std.mem.alignForward(u64, size, self.page_size);

        // 查找对应的块
        for (self.free_blocks.items) |*block| {
            if (!block.free and block.base == addr and block.size == aligned_size) {
                block.free = true;
                // TODO: 合并相邻的空闲块
                return true;
            }
        }

        return false; // 没有找到对应的块
    }

    // 映射内存（在实际系统中会操作页表）
    pub fn mapMemory(
        _: *MemoryManager,
        virt_addr: api.VirtualAddress,
        phys_addr: api.PhysicalAddress,
        size: u64,
        perms: api.MemoryPermissions,
    ) !void {
        // 在实际系统中，这里会更新页表来建立虚拟地址到物理地址的映射
        // 这里我们只是记录这个操作
        std.log.info("Mapping memory: virt={x}, phys={x}, size={x}, perms={{r:{}, w:{}, x:{}}}", .{ 
            virt_addr, phys_addr, size, perms.read, perms.write, perms.execute 
        });
    }

    // 解除内存映射
    pub fn unmapMemory(
        _: *MemoryManager,
        virt_addr: api.VirtualAddress,
        size: u64,
    ) !void {
        // 在实际系统中，这里会更新页表来解除虚拟地址到物理地址的映射
        // 这里我们只是记录这个操作
        std.log.info("Unmapping memory: virt={x}, size={x}", .{ virt_addr, size });
    }

    // 获取内存信息
    pub fn getMemoryInfo(self: *MemoryManager) struct { total: u64, free: u64 } {
        var total: u64 = 0;
        var free: u64 = 0;

        for (self.memory_regions.items) |region| {
            total += region.size;
            if (region.type == .free) {
                free += region.size;
            }
        }

        return .{ .total = total, .free = free };
    }

    // 清理资源
    pub fn deinit(self: *MemoryManager, _: std.mem.Allocator) void {
        self.memory_regions.deinit();
        self.free_blocks.deinit();
    }
};

// 全局内存管理器实例（用于API访问）
pub var global_memory_manager: MemoryManager = undefined;